package com.bjpowernode.p2p.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.bjpowernode.common.constant.Constants;
import com.bjpowernode.p2p.mapper.user.FinanceAccountMapper;
import com.bjpowernode.p2p.mapper.user.UserMapper;
import com.bjpowernode.p2p.model.user.FinanceAccount;
import com.bjpowernode.p2p.model.user.User;
import com.bjpowernode.p2p.service.UserService;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;



import java.util.Date;

@Component
@Service(interfaceClass = UserService.class,version = "1.0-SNAPSHOT",timeout = 15000)
public class UserServiceImpl implements UserService {


    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;


    @Autowired
    private FinanceAccountMapper financeAccountMapper;
    /**
     *
     * @return 返回所有平台用户的数量
     */

    @Override
    public Integer queryAllUser() {
        //访问redis数据库
        Integer allUserCount = (Integer) redisTemplate.opsForValue().get(Constants.ALL_USER_COUNT);
        //加锁：如果不加锁，那么多个用户同时访问，那么访问存储redis就没什么意义了
        if(!ObjectUtils.allNotNull(allUserCount)){
            synchronized (this){//加锁后，就保证如果没有从redis获取数据，那么先去获取并存入redis
                //双重验证：再次验证redis是否存在：这样可以使得当我们前一个线程刚把数据存入redis,后面的线程以及进入到了等待拿锁
                //所以双重验证使得我们存取redis才会有意义：使用锁的时候，多数会选择使用双重验证
                allUserCount =(Integer) redisTemplate.opsForValue().get(Constants.ALL_USER_COUNT);
                if(!ObjectUtils.allNotNull(allUserCount)){//如果访问redis没有结果，则进行数据库查询
                    allUserCount = userMapper.selectAllUser();
                    redisTemplate.opsForValue().set(Constants.ALL_USER_COUNT,allUserCount);
                }
            }
        }
        return allUserCount;
    }

    /**
     * 验证手机号是否被注册
     * @param phone
     * @return
     */
    @Override
    public User queryPhone(String phone) {

        return  userMapper.selectUserByPhone(phone);
    }

    /**
     * 注册账号
     * @param phone
     * @param loginPassword
     * @return
     */
    @Override
    @Transactional/*开启事务*/
    public User addUser(String phone, String loginPassword) throws Exception {
        User user = new User();
        user.setPhone(phone);
        user.setLoginPassword(loginPassword);
        user.setAddTime(new Date());
       user.setLastLoginTime(new Date());
        int i =userMapper.insert(user);
        if(i<=0){
            throw new Exception("注册失败！");
        }
        User userByPhone = userMapper.selectUserByPhone(phone);

        //注册金融账户：
        FinanceAccount financeAccount = new FinanceAccount();
        financeAccount.setAvailableMoney(888.0);
        financeAccount.setUid(userByPhone.getId());
        int result = financeAccountMapper.insert(financeAccount);
        if(result<=0){
            throw new Exception("注册金融账户失败！");
        }

        return userByPhone;
    }

    @Override
    public int modifyUser(User user) {
        return userMapper.updateByPrimaryKey(user);
    }
    /**
     * 登录验证
     * */
    @Override
    public User queryLoginCheck(String phone, String loginPassword) {
        //查询该账户是否存在
               return  userMapper.selectLoginCheck(phone,loginPassword);
    }

    @Override
    public User queryUser(Integer id) {
        return userMapper.selectUserById(id);
    }
}
